from django.contrib.auth.models import AbstractUser
from django.db import models
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from django.conf import settings

from meiduo_mall.utils.models import BaseModel
from .constants import VERIFY_EMAIL_TOKEN_EXPIRES


class User(AbstractUser):
    """用户模型类，继承django提供的用户抽象模型类AbstractUser"""
    # 添加手机号字段
    mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
    # 添加邮箱验证状态字段， 默认为False
    email_active = models.BooleanField(default=False, verbose_name='邮箱验证状态')
    # 添加默认地址字段, on_delete=models.SET_NULL删除的时候，外键字段被设置为空
    default_address = models.ForeignKey('Address', related_name='users', null=True, blank=True,
                                        on_delete=models.SET_NULL, verbose_name='默认地址')

    def generate_verify_email_url(self):
        """生成验证邮箱的url"""
        serializer = Serializer(settings.SECRET_KEY, VERIFY_EMAIL_TOKEN_EXPIRES)
        data = {
            'user_id': self.id,
            'email': self.email
        }
        # 需要解码
        token = serializer.dumps(data).decode()
        # 拼接邮箱验证链接地址
        verify_url = settings.VERIFY_EMAIL_HTML + '?token=' + token
        # 返回邮箱验证地址
        return verify_url

    class Meta:
        # 自定义表名
        db_table = 'tb_users'
        # 模型类在管理后台显示的名字
        verbose_name = '用户'
        # 去掉复数的s
        verbose_name_plural = verbose_name


class Address(BaseModel):
    """用户地址模型类"""
    # related_name表示反向关联属性，on_delete=models.CASCADE表示删除主键时，外键也删除，级联删除
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='addresses', verbose_name='用户')
    title = models.CharField(max_length=20, verbose_name='地址名称')
    receiver = models.CharField(max_length=20, verbose_name='收货人')
    # 指明外键ForeignKey时，可以使用字符串应用名.模型类名来定义，on_delete=models.PROTECT表示保护模式，主键删除的时候，必须外键先被删除，保护
    province = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='province_addresses',
                                 verbose_name='省')
    city = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='city_addresses', verbose_name='市')
    district = models.ForeignKey('areas.Area', on_delete=models.PROTECT, related_name='district_addresses',
                                 verbose_name='区')
    place = models.CharField(max_length=50, verbose_name='地址')
    mobile = models.CharField(max_length=11, verbose_name='手机')
    tel = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name='固定电话')
    email = models.CharField(max_length=30, null=True, blank=True, default='', verbose_name='电子邮箱')
    # 逻辑删除
    is_deleted = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_address'
        verbose_name = '用户地址'
        verbose_name_plural = verbose_name
        # 指定查询时默认按照更新时间字段倒序排序
        ordering = ['-update_time']
